package com.yxw.yx_hotel.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yxw.yx_hotel.dto.*;
import com.yxw.yx_hotel.entity.YxRoomBedEntity;
import com.yxw.yx_hotel.entity.YxRoomEntity;
import com.yxw.yx_hotel.entity.YxStayInEntity;
import com.yxw.yx_hotel.mapper.RoomBedMapper;
import com.yxw.yx_hotel.mapper.RoomMapper;
import com.yxw.yx_hotel.mapper.StayInMapper;
import com.yxw.yx_hotel.service.FileService;
import com.yxw.yx_hotel.service.RoomService;
import com.yxw.yx_hotel.entity.YxFileEntity;
import com.yxw.yx_hotel.utils.PageUtils;
import com.yxw.yx_hotel.utils.UserUtil;
import com.yxw.yx_hotel.vo.*;
import com.yxw.yxnet_cd_center.common.dto.PageVO;
import com.yxw.yxnet_cd_center.common.exception.BaseException;
import com.yxw.yxnet_cd_center.common.utils.BaseDateTime;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
/**
 *  宿舍管理
 * @author liuxin
 * @date 2024.01.17
 */
@Service
public class RoomServiceImpl extends ServiceImpl<RoomMapper, YxRoomEntity> implements RoomService {

    @Autowired
    private UserUtil  userUtil;

    @Autowired
    private RoomBedMapper roomBedMapper;

    @Autowired
    private StayInMapper stayInMapper;

    @Autowired
    private FileService  fileService;

    @Autowired
    private RoomMapper roomMapper;

    /**
     * 新增宿舍
     * @param dto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addRoom(AddRoomDto dto) {
        UserTokenVo userVo = userUtil.getLoginUserVo();
        //通用校验
        validata(dto,0);
        YxRoomEntity entity = new YxRoomEntity();
        BeanUtils.copyProperties(dto,entity);
        entity.setCreateId(userVo.getUserId());
        entity.setCreateName(userVo.getNickName());
        entity.setCreateTime(new Date());
        entity.setStatus(1);
        entity.setTenantId(userVo.getTenantId());
        if(null == entity.getRoomId())
        {
            entity.setRoomId(IdWorker.getId());
        }
        baseMapper.insert(entity);
        //新增床位信息
        List<AddRoomBedDto> bedNameList = dto.getBedList();
        List<YxRoomBedEntity> bedList=new ArrayList<>();
        for (int i = 0; i <bedNameList.size() ; i++) {
            AddRoomBedDto addRoomBedDto = bedNameList.get(i);
            YxRoomBedEntity bedEntity = new YxRoomBedEntity();
            bedEntity.setBedName(addRoomBedDto.getBedName().trim());
            bedEntity.setRoomName(entity.getRoomName());
            bedEntity.setRoomId(entity.getRoomId());
            bedEntity.setCreateId(userVo.getUserId());
            bedEntity.setCreateName(userVo.getNickName());
            bedEntity.setCreateTime(new Date());
            bedEntity.setTenantId(entity.getTenantId());
            bedEntity.setStatus(2);
            bedEntity.setBedId(IdWorker.getId());
            bedList.add(bedEntity);
        }
        roomBedMapper.addRoomBedByBatch(bedList);
    }

    /**
     * 修改宿舍
     * @param dto
     */
    @Override
    @Transactional(rollbackFor=Exception.class)
    public void updateRoom(AddRoomDto dto) {
        UserTokenVo userVo = userUtil.getLoginUserVo();
        //通用校验
        validata(dto,1);
        if(null==dto.getRoomId()){
            throw new BaseException("宿舍ID不能为空");
        }
        YxRoomEntity roomEntity = baseMapper.selectById(dto.getRoomId());
        if(null==roomEntity){
            throw new BaseException("未查询到宿舍信息");
        }
        BeanUtils.copyProperties(dto,roomEntity);
        if(StrUtil.isNotBlank(dto.getRendBackTime())){
            roomEntity.setRendBackTime(BaseDateTime.getDate(dto.getRendBackTime()));
        }
        
        //床位信息
        List<AddRoomBedDto> bedList = dto.getBedList();
        List<YxRoomBedEntity> addBedList=new ArrayList<>();
        List<YxRoomBedEntity> editBedList=new ArrayList<>();
        for (AddRoomBedDto bedDto: bedList) {
            Long bedId = bedDto.getBedId();
            YxRoomBedEntity yxRoomBedEntity = null;
            if(null != bedId){
                yxRoomBedEntity = roomBedMapper.selectById(bedId);
                if(null == yxRoomBedEntity)
                {
                    bedId = null;
                }
            }
            //新增床位
            if(null == yxRoomBedEntity){
                YxRoomBedEntity bedEntity = new YxRoomBedEntity();
                bedEntity.setBedName(bedDto.getBedName());
                bedEntity.setRoomName(dto.getRoomName());
                bedEntity.setRoomId(dto.getRoomId());
                bedEntity.setCreateId(userVo.getUserId());
                bedEntity.setCreateName(userVo.getNickName());
                bedEntity.setCreateTime(new Date());
                bedEntity.setTenantId(roomEntity.getTenantId());
                bedEntity.setStatus(0);
                addBedList.add(bedEntity);
            }
            else{
                if(!yxRoomBedEntity.getBedName().equals(bedDto.getBedName().trim())){
                    yxRoomBedEntity.setBedName(bedDto.getBedName().trim());
                    editBedList.add(yxRoomBedEntity);
                }
                //System.out.println("-------------------------------------------------------------------------");
                //System.out.println(JSON.toJSON(yxRoomBedEntity).toString());
            }
        }
        baseMapper.updateById(roomEntity);
        if(!addBedList.isEmpty()){
            roomBedMapper.addRoomBedByBatch(addBedList);
        }
        if(!editBedList.isEmpty()){
            roomBedMapper.updateRoomBedByBatch(editBedList);
        }
    }

    /**
     * 删除宿舍
     * @param roomId
     */
    @Override
    @Transactional(rollbackFor=Exception.class)
    public void deleteRoom(Long roomId) {
        //校验宿舍是否存在在住人员
        LambdaQueryWrapper<YxStayInEntity> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(YxStayInEntity::getRoomId, roomId);
        queryWrapper.eq(YxStayInEntity::getStatus, 1);
        Integer cnt = stayInMapper.selectCount(queryWrapper);
        if (cnt > 0) {
            throw new BaseException("该宿舍下有员工在住,不可删除");
        }
        baseMapper.deleteById(roomId);
        LambdaUpdateWrapper<YxRoomBedEntity> deleteWrapper = new LambdaUpdateWrapper();
        deleteWrapper.eq(YxRoomBedEntity::getRoomId, roomId);
        roomBedMapper.delete(deleteWrapper);
        //删除附件
        try{
            FileDeleteDto fileDto = new FileDeleteDto();
            fileDto.setBussId(roomId);
            fileService.deleteFile(fileDto);
        }catch (Exception e){
            log.error("删除附件失败：{}",e);
        }
    }

    /**
     * 查询宿舍列表
     * @param dto
     * @return
     */
    @Override
    public PageVO<YxRoomEntity> pageRoomList(QueryRoomDto dto) {
        List<RoomVo> voList=new ArrayList<>();
        Long tenantId = userUtil.getLoginTenantId();
        Page<YxRoomEntity> page = new Page<>(dto.getCurrPage(),dto.getPageSize());
        QueryWrapper<YxRoomEntity> queryWrapper=new QueryWrapper();
        queryWrapper.eq("tenant_id",tenantId);
        if(StringUtils.isNotBlank(dto.getRegionName())){
            queryWrapper.like("region_name",dto.getRegionName().trim());
        }
        if(StringUtils.isNotBlank(dto.getRoomName())){
            queryWrapper.like("room_name",dto.getRoomName().trim());
        }
        queryWrapper.ge(null!=dto.getCreateStartTime(),"create_time",dto.getCreateStartTime());
        queryWrapper.le(null!=dto.getCreateStartTime(),"create_time",dto.getCreateEndTime());
        queryWrapper.orderByDesc("create_time");
        queryWrapper.select("yx_room.*","(yx_room.bed_cnt-(select count(1) from yx_stay_in si where si.room_id=yx_room.room_id and si.status=1)) as remainBedCnt");
        Page<YxRoomEntity> entityPage = baseMapper.selectPage(page, queryWrapper);
        //List<YxRoomEntity> records = entityPage.getRecords();
        //if(null!=records && !records.isEmpty()){
        //    voList=BeanUtil.copyToList(records, RoomVo.class);
        //}
        return PageUtils.get(entityPage);
    }
    /**
     * 查询宿舍列表
     * @param dto
     * @return
     */
    @Override
    public List<YxRoomEntity> getRoomList(QueryRoomDto dto){
        Long tenantId = userUtil.getLoginTenantId();
        QueryWrapper<YxRoomEntity> queryWrapper=new QueryWrapper();
        queryWrapper.eq("tenant_id",tenantId);
        if(StringUtils.isNotBlank(dto.getRegionName())){
            queryWrapper.like("region_name",dto.getRegionName().trim());
        }
        if(StringUtils.isNotBlank(dto.getRoomName())){
            queryWrapper.like("room_name",dto.getRoomName().trim());
        }
        queryWrapper.ge(null!=dto.getCreateStartTime(),"create_time",dto.getCreateStartTime());
        queryWrapper.le(null!=dto.getCreateStartTime(),"create_time",dto.getCreateEndTime());
        queryWrapper.orderByDesc("create_time");
        queryWrapper.select("yx_room.*","(yx_room.bed_cnt-(select count(1) from yx_stay_in si where si.room_id=yx_room.room_id and si.status=1)) as remainBedCnt");
        //Page<YxRoomEntity> entityPage = baseMapper.selectPage(page, queryWrapper);
        List<YxRoomEntity> list = baseMapper.selectList(queryWrapper);
        return list;
    }
    /**
     * 查询宿舍详情
     * @param roomId
     * @return
     */
    @Override
    public RoomVo getRoomById(Long roomId) {
        RoomVo vo=new RoomVo();
        YxRoomEntity yxRoomEntity = baseMapper.selectById(roomId);
        if(null!=yxRoomEntity){
            BeanUtil.copyProperties(yxRoomEntity,vo);
            //查询床位信息
            List<RoomBedVo> bedList=roomBedMapper.getRoomBedByRoomId(roomId);
            vo.setBedList(bedList);
            List<YxFileEntity> fileList = fileService.getFilesByBussId(roomId);
            vo.setPictureList(fileList);
        }
        return vo;
    }

    /**
     * 房源统计列表查询
     * @param dto
     * @return
     */
    @Override
    public PageVO<RoomStatisticsVo> pageRoomStatisticsList(QueryRoomStatisticsDto dto) {
        Page<RoomStatisticsVo> page = new Page<>(dto.getCurrPage(),dto.getPageSize());
        List<RoomStatisticsVo> voList=roomMapper.pageRoomStatisticsList(page,dto);
        return PageUtils.get(page,voList);
    }

    /**
     * 房态管理-列表查询
     * @param dto
     * @return
     */
    @Override
    public PageVO<RoomManageVo> pageRoomManageList(QueryRoomManageDto dto) {
        UserTokenVo userVo = userUtil.getLoginUserVo();
        Page<RoomManageVo> page = new Page<>(dto.getCurrPage(),dto.getPageSize());
        List<RoomManageVo> voList=roomMapper.pageRoomManageList(page,dto,userVo.getTenantId());
        return PageUtils.get(page,voList);
    }

    /**
     * 根据宿舍ID查询床位列表
     * @param roomId
     * @return
     */
    @Override
    public List<RoomBedVo> getRoomBedByRoomId(Long roomId,Integer status) {
        List<RoomBedVo> voList=new ArrayList<>();
        LambdaQueryWrapper<YxRoomBedEntity> queryWrapper=new LambdaQueryWrapper();
        queryWrapper.eq(YxRoomBedEntity::getRoomId,roomId);
        queryWrapper.eq(null!=status,YxRoomBedEntity::getStatus,status);
        List<YxRoomBedEntity> yxRoomBedEntities = roomBedMapper.selectList(queryWrapper);
        if(null!=yxRoomBedEntities  && !yxRoomBedEntities.isEmpty()){
            voList=BeanUtil.copyToList(yxRoomBedEntities,RoomBedVo.class);
        }
        return voList;
    }

    //---------------------------------------------------------------------------------------------------------------

    /**
     * 新增宿舍校验
     * @param dto
     * @param type 1:修改 0：新增
     */
    private void validata(AddRoomDto dto,int type) {
        StringBuffer sbf=new StringBuffer();
        //校验床位数量和实际床位是否匹配
        List<AddRoomBedDto> bedList = dto.getBedList();
        if(dto.getBedCnt()!=bedList.size()){
            sbf.append("床位数量和实际新增床位数不匹配,床位数量为【"+dto.getBedCnt()+"】,实际新增床位【"+dto.getBedList().size()+"】</br>");
        }
        //床位名称去重校验
        List<String> bedNamList = bedList.stream().map(bed -> bed.getBedName()).collect(Collectors.toList());
        List<String> repeatList = bedNamList.stream()
                .filter((number -> Collections.frequency(bedNamList, number) > 1))
                .distinct()
                .collect(Collectors.toList());
        if(null!=repeatList && !repeatList.isEmpty()){
            sbf.append("以下床位名重复【"+(String.join(",", repeatList)+"】</br>"));
        }
        //校验同区域下面是否存在宿舍名字重复
        LambdaQueryWrapper<YxRoomEntity> queryWrapper=new LambdaQueryWrapper();
        queryWrapper.eq(YxRoomEntity::getRegionId,dto.getRegionId());
        queryWrapper.eq(YxRoomEntity::getRoomName,dto.getRoomName().trim());
        queryWrapper.ne(1==type,YxRoomEntity::getRoomId,dto.getRoomId());
        YxRoomEntity entity = baseMapper.selectOne(queryWrapper);
        if(null!=entity){
            sbf.append("该区域下已存在名叫【"+dto.getRoomName()+"】的宿舍</br>");
        }
        if(StringUtils.isNotBlank(sbf.toString())){
            throw new BaseException(sbf.toString());
        }
    }
}
